/*
 * File Name: ProtoFieldDescriptor.h
 *
 * Created on: 2021-01-28
 * Author: glendy ganby@163.com
 *
 * Last Modified: 2021-01-28
 * Description:
 */

#ifndef _PROTOFIELDDESCRIPTOR_H_
#define _PROTOFIELDDESCRIPTOR_H_

#include <string>
#include <stdint.h>

namespace miniproto
{
class MessageFactory;
class Message;

class ProtoFieldDescriptor
{
public:
	enum{
		BOOL = 0x01,
		INT32,
		INT64,
		UINT32,
		UINT64,
		FLOAT,
		DOUBLE,
		STRING,
		BYTES,
		MESSAGE,

		ARRAY = 0x040
	};

	enum {
	    WIRE_VARINT = 0,
	    WIRE_DOUBLE = 1,
	    WIRE_STRING_OR_MESSAGE = 2,
	    WIRE_FLOAT = 5
	};

	ProtoFieldDescriptor();
	~ProtoFieldDescriptor();
	void set(const uint8_t field_type, const ::std::string &field_name, const uint32_t number);
	void set_message(const uint8_t field_type, const ::std::string &field_name, const uint32_t number, ::miniproto::Message *message);
	uint8_t field_type() const;
	bool is_array() const;
	uint8_t base_field_type() const;
	const ::std::string &field_name() const;
	uint32_t number() const;

	int32_t wire_type() const;
	// number << 3  | wire_type
	uint32_t wire_tag() const;

	void wire_tag_split(const uint32_t tag, uint32_t *number, int32_t *wire_type);

	::miniproto::Message *NewMessage() const;

private:
	uint8_t field_type_;	//
	::std::string field_name_;
	uint32_t number_;
	::miniproto::Message *message_;
};

} // namespace miniproto

#endif //_PROTOFIELDDESCRIPTOR_H_
